#include <iostream>
#include <thread>
#include <unistd.h>
#include <mutex>
using namespace std;
constexpr int MAX_NUM = 10000;
int number;
mutex mtx;
void fun(string name)
{
    for (int i = 0; i < MAX_NUM; ++i)
    {
        // mtx.lock();
        // lock_guard guard(mtx); // c++17 支持模板形参推导
        // lock_guard<mutex> guard(mtx);
        // 使用新版本的 的上锁机制
        scoped_lock<mutex> lck(mtx);
        ++number;
        cout << "Thread " + name + " id = " << this_thread::get_id() << " number = " << number << endl;
        // mtx.unlock();
        usleep(10);
    }
}
void funA()
{
    for (int i = 0; i < MAX_NUM; ++i)
    {
        // mtx.lock();
        lock_guard guard(mtx);
        ++number;
        cout << "Thread A id = " << this_thread::get_id() << " number = " << number << endl;
        // mtx.unlock();
        usleep(10);
    }
}
void funB()
{
    for (int i = 0; i < MAX_NUM; ++i)
    {
        // mtx.lock();
        lock_guard guard(mtx);
        ++number;
        cout << "Thread B id = " << this_thread::get_id() << " number = " << number << endl;
        // mtx.unlock();
        usleep(10);
    }
}
void funC()
{
    for (int i = 0; i < MAX_NUM; ++i)
    {
        // mtx.lock();
        lock_guard guard(mtx);
        ++number;
        cout << "Thread C id = " << this_thread::get_id() << " number = " << number << endl;
        // mtx.unlock();
        usleep(10);
    }
}

int main()
{
    thread thr1(fun, "A");
    thread thr2(fun, "B");
    thread thr3(fun, "C");
    thr1.join();
    thr2.join();
    thr3.join();
    // detach 线程分离 detach之后会在后台运行中 在后台进行的守护进程 后面被c++的运行时库接管
    // 一旦detach 就不能在join了 否则系统会有异常
    cout << "thread1 and thread2 and thread3 completed." << endl;
    return 0;
}
